using System.Linq;
using Engine;
using Engine.Graphics;

namespace RuthlessConquest {
    public class CameraModule : Module {
        public double StartTime = double.MinValue;

        public Planet StartingPlanet;

        public Vector2 ViewCenter { get; set; }

        public float ViewScale { get; set; }

        public Matrix WorldToScreenMatrix { get; set; }

        public Matrix ScreenToWorldMatrix { get; set; }

        public PrimitivesRenderer2D PrimitivesRenderer { get; } = new();

        public CameraModule(Game game) : base(game) {
            ViewCenter = new Vector2(Game.WorldSize.X, Game.WorldSize.Y) / 2f;
            ViewScale = 1f;
        }

        public void Update() {
            if (StartingPlanet == null) {
                StartingPlanet = PlanetsModule.Planets.FirstOrDefault(p => p.IsControllingPlayerPlanet);
            }
            else {
                if (!StepModule.IsGameStarted) {
                    StartTime = Time.FrameStartTime;
                }
                double num = Time.FrameStartTime - StartTime;
                float x = (float)MathUtils.Saturate(0.3 * (num - 1.0));
                x = MathUtils.Sigmoid(x, 7f);
                ViewCenter = Vector2.Lerp(new Vector2(StartingPlanet.Position), new Vector2(Game.WorldSize) / 2f, x);
                ViewScale = MathUtils.Pow(3f, 1f - x);
            }
            GameWidget gameWidget = Game.Screen.GameWidget;
            BoundingRectangle boundingRectangle = new(Vector2.Zero, gameWidget.ActualSize);
            Vector2 vector = (boundingRectangle.Min + boundingRectangle.Max) / 2f;
            Vector2 vector2 = boundingRectangle.Max - boundingRectangle.Min;
            float x2 = vector2.X / Game.WorldSize.X;
            float x3 = vector2.Y / Game.WorldSize.Y;
            float num2 = MathUtils.Min(x2, x3);
            WorldToScreenMatrix = Matrix.CreateTranslation(0f - ViewCenter.X, 0f - ViewCenter.Y, 0f)
                * Matrix.CreateScale(ViewScale * num2, ViewScale * num2, 1f)
                * Matrix.CreateTranslation(vector.X, vector.Y, 0f)
                * gameWidget.GlobalTransform;
            ScreenToWorldMatrix = Matrix.Invert(WorldToScreenMatrix);
        }
    }
}